//
// Created by gushen610140 on 2024/3/14.
//

#ifndef DATASTRUCTURECOURSE_GSTACK_H
#define DATASTRUCTURECOURSE_GSTACK_H

template<typename T>
class [[maybe_unused]] GStack {
private:
    T *_data;
    T *_top;
    int _size;

    const int init_size = 10;
    const int increment_size = 10;

    [[maybe_unused]] void expand() {
        _data = (T *) std::realloc(_data, sizeof(T) * (_size + increment_size));
        if (!_data) {
            throw std::bad_alloc();
        }
        _top = _data + _size;
        _size += increment_size;
    }

public:
    [[maybe_unused]] void clear() {
        _top = _data;
    }

    [[maybe_unused]] bool empty() {
        return _data == _top;
    }

    [[maybe_unused]] int length() {
        return _top - _data;
    }

    [[maybe_unused]] void push(T value) {
        if (_top - _data >= _size) {
            expand();
        }
        *_top++ = value;
    }

    [[maybe_unused]] T top() {
        return *(_top - 1);
    }

    [[maybe_unused]] void pop() {
        if (_top == _data) {
            throw std::out_of_range("Stack is empty");
        }
        _top--;
    }

    // 重构带返回值的出栈
    [[maybe_unused]] void pop(T &res) {
        res = top();
        pop();
    }

    GStack() {
        _data = (T *) malloc(sizeof(T) * init_size);
        if (!_data) {
            throw std::bad_alloc();
        }
        _size = init_size;
        _top = _data;
    }

    ~GStack() {
        if (_data) {
            delete[] _data;
        }
        _size = 0;
    }
};

#endif //DATASTRUCTURECOURSE_GSTACK_H
